--- id: TASK-015 title: 'Dashboard state filter: live / recent / upcoming' status: "\U0001F3C1 Done" assignee: - '@humdrum-tiv' created_date: '2026-06-17 03:17' updated_date: '2026-06-18 01:17' labels: - feature dependencies: [] priority: high ordinal: 15000 --- ## Description On the dashboard (esp. all-leagues), let users filter the slate by game state so they don't scroll: All / Live / Recent (finals) / Upcoming. A key cycles the filter; a chip row shows the active one. Applies across leagues in all-leagues view and selects which buckets show in single-league view. ## Acceptance Criteria - [x] #1 A state filter (All/Live/Recent/Upcoming) is cyclable via a key and shown as a chip row under the league tabs - [x] #2 All-leagues view honors the state filter across every league (live=in-progress, recent=finals, upcoming=scheduled) - [x] #3 Single-league view shows only the buckets matching the filter - [x] #4 Cursor/selection stays valid when the filter changes (clamped) ## Implementation Notes Added gameFilter enum (All/Live/Recent/Upcoming) + App.stateFilter; 's' cycles, resets cursor. sections() delegates to filteredSections/leagueSlate when active: pulls games of that state from full window (live keeps client order, recent most-recent-first, upcoming chronological), no favorites pin. stateTabs() chip row under league tabs; dashboard chrome 5->6; footer 's filter' hint. Also fixed bases diamond (equal-width rows so 2nd centers over the gap). ## Final Summary Adds a dashboard state filter so users can see just live games, recent finals, or upcoming fixtures without scrolling (TASK-015). New gameFilter enum + App.stateFilter cycled with 's', shown as a highlighted chip row (stateTabs) beneath the league tabs. When active, sections() routes through filteredSections/leagueSlate: games of the chosen state from the full fetched window, ordered per filter, with the favorites pin dropped so the view is purely that state; all-leagues keeps per-league grouping, single-league collapses to one labeled section. Cursor resets/clamps on change. Bundled a fix for the bases diamond (rows were 5 vs 4 wide, skewing 2nd base off-center — now equal width). Offline tests for live/recent/upcoming behavior + diamond width; go vet/build + full suite green.